home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / uucico_s.lha / sysdep.c < prev    next >
C/C++ Source or Header  |  1992-12-01  |  14KB  |  731 lines

  1.  
  2. /*
  3.  *  SYSDEP.C
  4.  *
  5.  *  $Header: Beta:src/uucp/src/uucico/RCS/sysdep.c,v 1.1 90/02/02 11:56:16 dillon Exp Locker: dillon $
  6.  *
  7.  * (C) Copyright 1987 by John Gilmore
  8.  * Copying and use of this program are controlled by the terms of the Free
  9.  * Software Foundation's GNU Emacs General Public License.
  10.  *
  11.  *  Amiga Changes Copyright 1988 by William Loftus. All rights reserved.
  12.  *  Additional chgs Copyright 1989 by Matthew Dillon, All Rights Reserved.
  13.  */
  14.  
  15. #include <exec/types.h>
  16. #include <exec/exec.h>
  17. #include "includes.h"
  18. #include <hardware/cia.h>
  19. #include <devices/timer.h>
  20. #include <devices/serial.h>
  21. #include <libraries/dos.h>
  22. #include <pwd.h>
  23. #include "uucp.h"
  24. #include "version.h"
  25. #include <OwnDevUnit.h>
  26.  
  27. #define Assert(x)   if (!(x)) _assert_failed(__LINE__);
  28.  
  29. Prototype int openout(char *, int);
  30. Prototype int sigint(void);
  31. Prototype void cleanup(void);
  32. Prototype int xdatardy(void);
  33. Prototype int xgetc(int);
  34. Prototype int xwrite(const void *, int);
  35. Prototype int xwritea(const void *, int);
  36. Prototype int xxwrite(const void *, int, int);
  37. Prototype void SendBreak(void);
  38. Prototype int CheckCarrier(void);
  39. Prototype void *bzero(void *, long);
  40. Prototype void *bcopy(const void *, void *, long);
  41. Prototype void munge_filename(char *, char *);
  42. Prototype int hangup(void);
  43. Prototype int work_scan(char *);
  44. Prototype char *work_next(void);
  45. Prototype void amiga_setup(void);
  46. Prototype void set_baud(int);
  47. Prototype void OpenSerial(int);
  48. Prototype void CloseSerial(int);
  49. Prototype void xexit(int);
  50. Prototype void printc(unsigned char);
  51. Prototype void NiceAbortIO(void *);
  52.  
  53. static void _assert_failed(int);
  54.  
  55. IDENT(".03");
  56.  
  57. /*
  58.  *  Split out of uuslave.c by John Gilmore, 8 August 1987.
  59.  *  ported to the Amiga by William Loftus, 20 September 1987.
  60.  *  rewritten by Matthew Dillon, October 1989
  61.  */
  62.  
  63. /* FIXME -- System dependent defines (not really -- should be in a .h) */
  64. /*
  65.  * Timeout for raw characters -- if we don't hear a char within BYTE_TIMEOUT
  66.  * seconds, we assume the other side has gone away.  Has nothing to do with
  67.  * retransmission timeouts (if any!).
  68.  */
  69.  
  70. extern int debug;
  71. extern int SevenWire;
  72.  
  73. #define FAILURE  1
  74.  
  75. struct IOExtSer Iosr;
  76. struct IOExtSer Iosw;
  77. struct IOExtSer Ioss;
  78. struct timerequest Iot0;
  79. char   *OldTaskName;
  80.  
  81. char    *DeviceName = "serial.device";
  82. long    DeviceUnit = 0;
  83.  
  84. unsigned char    XInBuf[256];       /*  for xgetc() */
  85. char    LockFileName[128];
  86. short    XInIdx = 0;
  87. short    XInLen = 0;
  88. short    IoswIP = 0;
  89. short    IosrIP = 0;
  90. short    IotIP = 0;
  91.  
  92. short    InExitRoutine = 0;
  93. short    debugRead = 0;
  94.  
  95. extern char path[];
  96. extern int Getty;
  97. extern int IgnoreCD;
  98.  
  99. int
  100. openout(acu, baud)
  101. char *acu;
  102. int  baud;
  103. {
  104.     set_baud(baud);
  105.  
  106.     return SUCCESS;
  107. }
  108.  
  109. /*
  110.  * Basement level I/O routines
  111.  *
  112.  * xwrite() writes a character string to the serial port
  113.  * xgetc() returns a character from the serial port, or an EOF for timeout.
  114.  * sigint() restores the state of the serial port on exit.
  115.  */
  116.  
  117. int
  118. sigint()
  119. {
  120.     xexit(10);
  121.     return(0);
  122. }
  123.  
  124.  
  125. void
  126. cleanup()
  127. {
  128.  
  129.     signal(SIGINT, SIG_IGN);
  130.  
  131.     ++InExitRoutine;
  132.  
  133.     if (InExitRoutine == 1 && Iosr.IOSer.io_Device && CheckCarrier())
  134.     reset_modem();
  135.  
  136.     CloseSerial(1);
  137.  
  138.     {
  139.     struct Task *task = (struct Task *)FindTask(NULL);
  140.     if (OldTaskName)
  141.         task->tc_Node.ln_Name = OldTaskName;
  142.     }
  143.  
  144.     if (Iot0.tr_node.io_Device) {
  145.     CloseDevice(&Iot0);
  146.     Iot0.tr_node.io_Device = NULL;
  147.     }
  148.     if (Iot0.tr_node.io_Message.mn_ReplyPort) {
  149.     DeletePort(Iot0.tr_node.io_Message.mn_ReplyPort);
  150.     Iot0.tr_node.io_Message.mn_ReplyPort = NULL;
  151.     }
  152.     chdir(path);
  153.  
  154.     mountrequest(1);
  155.  
  156.     UnLockFiles();      /*  unlock any hanging locks */
  157. }
  158.  
  159. int
  160. xdatardy()
  161. {
  162.     if (XInIdx != XInLen)
  163.     return(1);
  164.     CheckCarrier();
  165.     return (Ioss.IOSer.io_Actual > 0);
  166. }
  167.  
  168. int
  169. xgetc(byteto)
  170. int byteto;
  171. {
  172.     int ch, n;
  173.     long smask;
  174.     long tmask;
  175.     short bytetimeout;
  176.  
  177. top:
  178.     if (XInIdx != XInLen) {
  179.     if (debug > 8) {
  180.         if (debugRead == 0)
  181.         printf("\nREAD: ");
  182.         debugRead = 1;
  183.         printc(XInBuf[XInIdx]);
  184.     }
  185.         xfer.bytes_recv++;
  186.     return((int)XInBuf[XInIdx++]);
  187.     }
  188.  
  189.     XInIdx = 0;
  190.     XInLen = 0;
  191.  
  192.     if (!CheckCarrier())                        /*  carrier lost?     */
  193.     return(EOF);
  194.  
  195.     Assert(Iosr.IOSer.io_Device);
  196.  
  197.     if ((n = Ioss.IOSer.io_Actual) > 0) {       /*  at least one..    */
  198.     Iosr.IOSer.io_Command = CMD_READ;
  199.     Iosr.IOSer.io_Data = (APTR)XInBuf;
  200.     if (n > sizeof(XInBuf))
  201.         n = sizeof(XInBuf);
  202.     Iosr.IOSer.io_Length = n;
  203.     DoIO(&Iosr);
  204.     if (Iosr.IOSer.io_Actual > 0) {
  205.         if (debug > 8)
  206.         printf("(r%d/%d)", n, Iosr.IOSer.io_Actual);
  207.         XInIdx = 0;
  208.         XInLen = Iosr.IOSer.io_Actual;
  209.         goto top;
  210.     }
  211.     }
  212.  
  213.     /*
  214.      *    no bytes ready, byteto is 0 (no wait)
  215.      */
  216.  
  217.     if (byteto == 0)
  218.     return(EOF);
  219.  
  220.     /*
  221.      *    no bytes ready, wait for one.
  222.      *
  223.      *    once every 3 seconds check carrier detect.
  224.      */
  225.  
  226.     bytetimeout = byteto;
  227.     Iot0.tr_time.tv_secs = 3;
  228.     Iot0.tr_time.tv_micro= 0;
  229.     SendIO(&Iot0);
  230.     IotIP = 1;
  231.  
  232.     Iosr.IOSer.io_Command = CMD_READ;
  233.     Iosr.IOSer.io_Data = (APTR)XInBuf;
  234.     Iosr.IOSer.io_Length = 1;
  235.     Iosr.IOSer.io_Actual = 0;    /*  trying to find a bug... */
  236.     SendIO(&Iosr);
  237.     IosrIP = 1;
  238.  
  239.     smask = 1L << Iosr.IOSer.io_Message.mn_ReplyPort->mp_SigBit;
  240.     tmask = 1L << Iot0.tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  241.  
  242.     for (;;) {
  243.     long mask = Wait(tmask | smask | SIGBREAKF_CTRL_C);
  244.  
  245.     if (mask & SIGBREAKF_CTRL_C) {
  246.         NiceAbortIO(&Iosr);
  247.         WaitIO(&Iosr);
  248.         IosrIP = 0;
  249.         AbortIO(&Iot0);
  250.         WaitIO(&Iot0);
  251.         IotIP = 0;
  252.         xexit(10);
  253.     }
  254.     if (CheckIO(&Iosr)) {
  255.         WaitIO(&Iosr);
  256.         IosrIP = 0;
  257.         AbortIO(&Iot0);
  258.         WaitIO(&Iot0);
  259.         IotIP = 0;
  260.  
  261.         ch = (int)XInBuf[0];
  262.  
  263.         if (debug > 8) {
  264.         if (debugRead == 0)
  265.             printf("\nREAD ");
  266.         debugRead = 1;
  267.         printf("(waitc%d)", Iosr.IOSer.io_Actual);
  268.         printc((unsigned char)ch);
  269.         }
  270.         xfer.bytes_recv++;
  271.         return(ch);
  272.     }
  273.     if (CheckIO(&Iot0)) {
  274.         WaitIO(&Iot0);
  275.         IotIP = 0;
  276.  
  277.         Iot0.tr_time.tv_secs = 3;
  278.         Iot0.tr_time.tv_micro= 0;
  279.  
  280.         bytetimeout -= Iot0.tr_time.tv_secs;
  281.         if (bytetimeout > 0) {
  282.         if (CheckCarrier() == 0) {
  283.             NiceAbortIO(&Iosr);
  284.             WaitIO(&Iosr);
  285.             IosrIP = 0;
  286.             break;
  287.         }
  288.         SendIO(&Iot0);
  289.         IotIP = 1;
  290.         } else {
  291.         NiceAbortIO(&Iosr);
  292.         WaitIO(&Iosr);
  293.         IosrIP = 0;
  294.         if (Iosr.IOSer.io_Actual == 1) {
  295.             xfer.bytes_recv++;
  296.             return((int)XInBuf[0]);
  297.         }
  298.         break;
  299.         }
  300.     }
  301.     }
  302.     if (debug > 8)
  303.     printf("\nRecv-EOF\n");
  304.     return(EOF);
  305. }
  306.  
  307. int
  308. xwrite(buf, ctr)
  309. const void *buf;
  310. int ctr;
  311. {
  312.     return(xxwrite(buf, ctr, 0));
  313. }
  314.  
  315. int
  316. xwritea(buf, ctr)
  317. const void *buf;
  318. int ctr;
  319. {
  320.     xxwrite(buf, ctr, 1);
  321.     return(ctr);
  322. }
  323.  
  324. int
  325. xxwrite(buf, ctr, async)
  326. const void *buf;
  327. int ctr;
  328. int async;
  329. {
  330.     Assert(Iosr.IOSer.io_Device);
  331.     if (debug > 8) {
  332.     short i;
  333.     if (debugRead)
  334.         printf("\nWRITE ");
  335.     debugRead = 0;
  336.     for (i = 0; i < ctr; ++i) {
  337.         printc(((unsigned char *)buf)[i]);
  338.     }
  339.     printf("\n");
  340.     }
  341.     if (IoswIP) {
  342.     WaitIO(&Iosw);
  343.     IoswIP = 0;
  344.     }
  345.  
  346.     Iosw.IOSer.io_Command = CMD_WRITE;
  347.     Iosw.IOSer.io_Length = ctr;
  348.     Iosw.IOSer.io_Data = (APTR)buf;
  349.     if (async) {
  350.     SendIO(&Iosw);
  351.     IoswIP = 1;
  352.     } else {
  353.     DoIO(&Iosw);
  354.     }
  355.     xfer.bytes_send += ctr;
  356.     return ctr;
  357. }
  358.  
  359. void
  360. SendBreak()
  361. {
  362.     Assert(Iosr.IOSer.io_Device);
  363.     Ioss.IOSer.io_Command = SDCMD_BREAK;
  364.     DoIO(&Ioss);
  365. }
  366.  
  367. int
  368. CheckCarrier()
  369. {
  370.     Assert(Iosr.IOSer.io_Device);
  371.     Ioss.IOSer.io_Command = SDCMD_QUERY;
  372.     DoIO(&Ioss);
  373.     if (IgnoreCD)
  374.     return(1);
  375.     if (Ioss.io_Status & CIAF_COMCD)    /*  non-zero == no carrier */
  376.     return(0);
  377.     return(1);
  378. }
  379.  
  380. void *
  381. bzero(s, cnt)
  382. void   *s;
  383. long   cnt;
  384. {
  385.     setmem(s, cnt, 0);
  386.     return(s);
  387. }
  388.  
  389. void *
  390. bcopy(from, to, cnt)
  391. const void   *from;
  392. void   *to;
  393. long   cnt;
  394. {
  395.     movmem(from, to, cnt);
  396.     return(to);
  397. }
  398.  
  399. /*
  400.  * Transform a filename from a uucp packet (in Unix format) into a local
  401.  * filename that will work in the local file system.
  402.  */
  403.  
  404. void
  405. munge_filename(s, d)
  406. char *s, *d;
  407. {
  408.     if (*s != '~') {
  409.     if (s != d)
  410.         strcpy(d, s);
  411.     return;
  412.     }
  413.  
  414.     /*
  415.      *    ~/ ...    convert to UUPUB:
  416.      *    ~user/...   convert to <homedir>/...
  417.      */
  418.  
  419.     {
  420.     short i;
  421.     short c;
  422.     char *t;
  423.     struct passwd *pw;
  424.  
  425.     for (i = 1; s[i] && s[i] != '/'; ++i);
  426.     c = s[i];
  427.  
  428.     s[i] = 0;
  429.     if (i == 1)
  430.         pw = NULL;
  431.     else
  432.         pw = getpwnam(s + 1);
  433.     s[i] = c;
  434.  
  435.     if (c == '/')
  436.         ++i;
  437.  
  438.     if (pw) {
  439.         t = malloc(strlen(pw->pw_dir) + strlen(s + i) + 1);
  440.         strcpy(t, pw->pw_dir);
  441.     } else {
  442.         t = malloc(strlen(s + i) + 32);
  443.         strcpy(t, GetConfigDir(UUPUB));
  444.     }
  445.     strcat(t, s + i);
  446.     strcpy(d, t);
  447.     free(t);
  448.     }
  449. }
  450.  
  451. int
  452. hangup()
  453. {
  454.     static char buf[128];
  455.  
  456.     reset_modem();
  457.  
  458.     sprintf(buf, "run >nil: <nil: %s", GetConfigProgram(UUXQT));
  459.  
  460.     if (PriMode)
  461.     SetTaskPri(FindTask(NULL), OldPri - 1);
  462.  
  463.     if (Execute(buf, NULL, NULL) == 0)
  464.     puts("Unable to run UUXQT");
  465.  
  466.     if (PriMode)
  467.     SetTaskPri(FindTask(NULL), OldPri + 1);
  468.  
  469.     return SUCCESS;
  470. }
  471.  
  472. static char names[MAXFILES*16];
  473. static char *pointers[MAXFILES];
  474. static int file_pointer;
  475.  
  476. int
  477. bp_strcmp(s1, s2)
  478. char **s1;
  479. char **s2;
  480. {
  481.     return(strcmp(*s1, *s2));
  482. }
  483.  
  484. int
  485. work_scan(system_name)
  486. char *system_name;
  487. {
  488.     static char name[128];
  489.     int count;
  490.  
  491.     file_pointer = 0;
  492.  
  493.     if (strlen(system_name) > 7)
  494.     system_name[7] = '\0';
  495.  
  496.     sprintf(name, "%sC.%s#?", MakeConfigPath(UUSPOOL, ""), system_name);
  497.  
  498.     if (debug > 2)
  499.     printf("Looking for %s\n",name);
  500.  
  501.     count = getfnl(name,names,sizeof(names),0);
  502.  
  503.     if (count > 0) {
  504.     if (strbpl(pointers,MAXFILES,names) != count) {
  505.         printf("Too many command files for %s.\n",system_name);
  506.         return(0);
  507.     }
  508.     } else {
  509.     return(0);
  510.     }
  511.     qsort(pointers, count, sizeof(char *), bp_strcmp);
  512.     if (debug > 2)
  513.     printf("Found -> %s\n", pointers[file_pointer]);
  514.     return(1);
  515. }
  516.  
  517. char *
  518. work_next()
  519. {
  520.     char *ptr;
  521.  
  522.     if (ptr = pointers[file_pointer]) {
  523.     if (debug > 2)
  524.         printf("Found -> %s\n", ptr);
  525.     ++file_pointer;
  526.     }
  527.     return(ptr);
  528. }
  529.  
  530. void
  531. amiga_setup()
  532. {
  533.     mountrequest(0);        /*  disallow requesters */
  534.  
  535.     OpenSerial(1);
  536.  
  537.     if (OpenDevice(TIMERNAME, UNIT_VBLANK, &Iot0, 0))  {
  538.     Iot0.tr_node.io_Device = NULL;
  539.     printf("Can't open timer device.");
  540.     xexit(10);
  541.     }
  542.  
  543.     Iot0.tr_node.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("UUCICO-Timer", 0L);
  544.     Iot0.tr_node.io_Command = TR_ADDREQUEST;
  545.     Iot0.tr_node.io_Error = 0;
  546.  
  547.     {
  548.     struct Task *task = (struct Task *)FindTask(NULL);
  549.     OldTaskName = task->tc_Node.ln_Name;
  550.     task->tc_Node.ln_Name = "uucico";
  551.     }
  552. }
  553.  
  554. void
  555. set_baud(baud)
  556. int baud;
  557. {
  558.     Assert(Iosr.IOSer.io_Device);
  559.  
  560.     /*
  561.      *    only modify serial parameters if not run from a Getty.    This is
  562.      *    to get around a bug in the A2232 serial.device (possibly also
  563.      *    the normal serial.device) having to do with hanging semaphores.
  564.      *
  565.      *    it is also possible that this might be desirable for operation.
  566.      */
  567.  
  568.     if (Getty == 0) {
  569.     Iosr.IOSer.io_Command = SDCMD_SETPARAMS;
  570.     Iosr.io_SerFlags =  SERF_SHARED | SERF_XDISABLED;
  571.     Iosr.io_Baud = baud;
  572.     Iosr.io_ReadLen = 8L;
  573.     Iosr.io_WriteLen = 8L;
  574.     Iosr.io_CtlChar = 0x11130000L;
  575.     Iosr.io_RBufLen = 4096;
  576.     Iosr.io_StopBits= 1;
  577.     Iosr.io_BrkTime = 500000;
  578.  
  579.     if (SevenWire)
  580.         Iosr.io_SerFlags |= SERF_7WIRE;
  581.  
  582.     DoIO(&Iosr);
  583.     }
  584. }
  585.  
  586. extern short DoAttempt;
  587.  
  588. void
  589. OpenSerial(lock)
  590. int lock;
  591. {
  592.     unsigned char *error;
  593.  
  594.     if (Iosr.IOSer.io_Device) {
  595.     puts("softerror, OpenSerial: Serial Port already open!");
  596.     return;
  597.     }
  598.  
  599.     Iosr.io_SerFlags = SERF_SHARED | SERF_XDISABLED;
  600.     Iosr.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Read_RS",0);
  601.  
  602.     if (SevenWire)
  603.     Iosr.io_SerFlags |= SERF_7WIRE;
  604.  
  605.     if (lock && Getty == 0) {
  606.     if (DoAttempt)
  607.         error = AttemptDevUnit(DeviceName, DeviceUnit, "UUcico", 0);
  608.     else
  609.         error = LockDevUnit(DeviceName, DeviceUnit, "UUcico", 0);
  610.  
  611.     if (error) {
  612.         if (error[0] == ODUERR_LEADCHAR[0])
  613.         printf("Unable to lock serial port: %s\n", &error[1]);
  614.         else
  615.         printf("%s unit %d already owned by %s\n",
  616.             DeviceName, DeviceUnit, error);
  617.  
  618.         xexit(10);
  619.     }
  620.     }
  621.  
  622.     if (OpenDevice(DeviceName, DeviceUnit, &Iosr, NULL)) {
  623.     Iosr.IOSer.io_Device = NULL;
  624.     DeletePort(Iosr.IOSer.io_Message.mn_ReplyPort);
  625.     Iosr.IOSer.io_Message.mn_ReplyPort = NULL;
  626.     printf("Can not open serial port for read.\n");
  627.     xexit(TRUE);
  628.     }
  629.  
  630.     Iosw = Iosr;
  631.     Iosw.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Write_RS", 0);
  632.     Ioss = Iosw;
  633.  
  634.     Iosr.IOSer.io_Command = SDCMD_QUERY;
  635.     DoIO(&Iosr);
  636.  
  637.     set_baud(Iosr.io_Baud);
  638. }
  639.  
  640. void
  641. CloseSerial(lock)
  642. int lock;
  643. {
  644.     if (IosrIP) {
  645.     NiceAbortIO(&Iosr);
  646.     WaitIO(&Iosr);
  647.     IosrIP = 0;
  648.     }
  649.     if (IotIP) {
  650.     AbortIO(&Iot0);
  651.     WaitIO(&Iot0);
  652.     IotIP = 0;
  653.     }
  654.     if (IoswIP) {
  655.     WaitIO(&Iosw);
  656.     IoswIP = 0;
  657.     }
  658.     if (Iosr.IOSer.io_Device) {
  659.     CloseDevice(&Iosr);
  660.     Iosr.IOSer.io_Device = NULL;
  661.     Iosw.IOSer.io_Device = NULL;
  662.     Ioss.IOSer.io_Device = NULL;
  663.     } else {
  664.     puts("softerr, CloseSerial: Serial Port already closed!");
  665.     }
  666.     if (Iosr.IOSer.io_Message.mn_ReplyPort) {
  667.     DeletePort(Iosr.IOSer.io_Message.mn_ReplyPort);
  668.     Iosr.IOSer.io_Message.mn_ReplyPort = NULL;
  669.     }
  670.     if (Iosw.IOSer.io_Message.mn_ReplyPort) {
  671.     DeletePort(Iosw.IOSer.io_Message.mn_ReplyPort);
  672.     Iosw.IOSer.io_Message.mn_ReplyPort = NULL;
  673.     }
  674.     if (lock && Getty == 0)
  675.     FreeDevUnit(DeviceName, DeviceUnit);
  676. }
  677.  
  678. void
  679. xexit(code)
  680. int code;
  681. {
  682.     cleanup();
  683.  
  684.     if (code)
  685.     printf("\nAbnormal Termination, code %d.\n", code);
  686.     exit(code);
  687. }
  688.  
  689. void
  690. printc(c)
  691. unsigned char c;
  692. {
  693.     c &= 0x7F;
  694.  
  695.     if (c < 32)
  696.     printf("^%c", c | 0x40);
  697.     else if (c == 32)
  698.     printf("_");
  699.     else if (c < 128)
  700.     printf("%c", c);
  701.     else
  702.     printf("(%02x)", c);
  703. }
  704.  
  705. void
  706. _assert_failed(line)
  707. {
  708.     static short reent;
  709.  
  710.     if (reent == 0) {
  711.     ++reent;
  712.     printf("Software Error line %d sysdep.c (uucico)\n", line);
  713.     xexit(20);
  714.     }
  715. }
  716.  
  717. /*
  718.  *  bug fix for older A2232 serial.device's
  719.  */
  720.  
  721. void
  722. NiceAbortIO(ior)
  723. void *ior;
  724. {
  725.     Disable();
  726.     if (((struct Message *)ior)->mn_Node.ln_Type != NT_REPLYMSG)
  727.     AbortIO(ior);
  728.     Enable();
  729. }
  730.  
  731.